package nr.nodehost;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
//import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.Socket;
import java.nio.ByteBuffer;
import java.util.Arrays;

@AllArgsConstructor
@NoArgsConstructor
@Data
public class CmdFrame implements Serializable {
    private int schemaId;              // 任务编号
    private int port_dataRemote;       // 给对方一个端口号，负责该任务的源数据的接收。对方向我们提供的该端口号建立连接并写数据。
    private int srcFrameLength;        // 对方告诉我们一帧的大小，我们每次读这么多，组一个原始帧，传给nodehost.
    private int dataAccess_StartStop;  // 0: start a new job;   1: stop the job.

    // Constructors, getters, and setters
    public  static CmdFrame readOneFrame(Socket socket){
        CmdFrame cf = new CmdFrame();
        int nRead = 0;
        try {
            InputStream is = socket.getInputStream();   // 不要放在try()括号里，自动关闭is, 会关闭对应的socket.
            //   System.out.println("DataFrame Obj is: " + this.getFrameNo() + ", socket " + socket  + ", inputStream " + is);
            byte[] buf = new byte[4];
            nRead = is.read(buf);
            cf.setSchemaId(ByteBuffer.wrap(buf).getInt());
            //   System.out.println(this.hashCode() + " " + nRead + " setSchemaId OK " + cf.getSchemaId());
            nRead = is.read(buf);
            cf.setPort_dataRemote(ByteBuffer.wrap(buf).getInt());
            // System.out.println(this.hashCode() + " " + nRead + " setPort_dataRemote OK " + cf.getPort_dataRemote());
            nRead = is.read(buf);
            cf.setSrcFrameLength(ByteBuffer.wrap(buf).getInt());
            //  System.out.println(this.hashCode() + " " + nRead + " setSrcFrameLength OK " + cf.getSrcFrameLength());
            nRead = is.read(buf);
            cf.setDataAccess_StartStop(ByteBuffer.wrap(buf).getInt());
            // System.out.println(this.hashCode() + " " + nRead + " setDataAccess_StartStop OK " + cf.getDataAccess_StartStop());

        } catch (IOException e) {
            e.printStackTrace();
        }
        return  cf;
    }


    public  byte[] serialize() throws  IOException{
        int pos = 0;
        byte[] data = new byte[4 + 4 + 4 + 4];  //start-stop, schemaid, port, length
        Utils.int2bytes(this.schemaId, data, pos);  pos += 4;              //schemaid
        Utils.int2bytes(this.port_dataRemote, data, pos);  pos += 4;       //port
        Utils.int2bytes(this.srcFrameLength,  data, pos);  pos += 4;       //length
        Utils.int2bytes(this.dataAccess_StartStop, data, pos);  pos += 4;  //start_stop
        return data;
    }

    // Deserialization method
    public static CmdFrame deserialize(byte[] bytes) throws IOException, ClassNotFoundException {
        ByteBuffer buffer = ByteBuffer.wrap(bytes);
        CmdFrame frame = new CmdFrame();
        // Read schemaId and frameNo as ints
        frame.schemaId = buffer.getInt();
        frame.port_dataRemote = buffer.getInt();
        frame.srcFrameLength  = buffer.getInt();
        frame.dataAccess_StartStop  = buffer.getInt();
        return frame;
    }

    public CmdFrame(int dataAccess_StartStop, int schemaId) {
        this.dataAccess_StartStop = dataAccess_StartStop;
        this.schemaId = schemaId;
    }



    @Override
    public String toString() {
        return "CmdFrame{" +
                "dataAccess_StartStop=" + dataAccess_StartStop +
                ", schemaId=" + schemaId +
                ", port_dataRemote=" + port_dataRemote +
                ", length=" + srcFrameLength +
                '}';
    }
}
